import lib_pulseaudio as pa
import gtk


def check(result):
    if result < 0:
        error = pa.pa_context_errno(context)
        raise MediaException(pa.pa_strerror(error))
    return result

def check_not_null(value):
    if not value:
        error = pa.pa_context_errno(context)
        raise MediaException(pa.pa_strerror(error))
    return value


class PulseAudio:
    context = None
    
    def __init__(self):
        win = gtk.Window()
        win.connect("destroy",gtk.main_quit)
        win.show_all()
        
        self.threaded_mainloop = pa.pa_threaded_mainloop_new()
        self.mainloop = pa.pa_threaded_mainloop_get_api(self.threaded_mainloop)
        pa.pa_threaded_mainloop_start(self.threaded_mainloop)
    
        #Persist callback types
        self.__pa_state_cb = pa.pa_context_notify_cb_t(self.py_state_cb)
        self.__pa_success_cb = pa.pa_context_success_cb_t(self.py_success_cb)
        
    def connect(self, app_name,server=None):
        '''Connect to pulseaudio server.
        
        :Parameters:
            `server` : str
                Server to connect to, or ``None`` for the default local
                server (which may be spawned as a daemon if no server is
                found).
                
        '''
        # TODO disconnect from old
        assert not self.context, 'Already connected'

        # Create context and connect
        #app_name = self.get_app_name()

        self.lock()
        self.context = pa.pa_context_new(self.mainloop, app_name)
        self.set_state_callback(self.py_state_cb,None)
        check(pa.pa_context_connect(self.context, server, 0, None))
        self.unlock()
        
    def set_state_callback(self,userdata=None):
        pa.pa_context_set_state_callback(self.context, self.__pa_state_cb,userdata)
        
    def lock(self):
        '''Lock the threaded mainloop against events.  Required for all
        calls into PA.'''
        pa.pa_threaded_mainloop_lock(self.threaded_mainloop)

    def unlock(self):
        '''Unlock the mainloop thread.'''
        pa.pa_threaded_mainloop_unlock(self.threaded_mainloop)

    def signal(self):
        '''Signal the mainloop thread to break from a wait.'''
        pa.pa_threaded_mainloop_signal(self.threaded_mainloop, 0)

    def wait(self):
        '''Wait for a signal.'''
        pa.pa_threaded_mainloop_wait(self.threaded_mainloop)

    def sync_operation(self, op):
        '''Wait for an operation to be done or cancelled, then release it.
        Uses a busy-loop -- make sure a callback is registered to 
        signal this listener.''' 
        while pa.pa_operation_get_state(op) == pa.PA_OPERATION_RUNNING:
            pa.pa_threaded_mainloop_wait(self.threaded_mainloop)
        pa.pa_operation_unref(op)

    def async_operation(self, op):
        '''Release the operation immediately without waiting for it to
        complete.'''
        pa.pa_operation_unref(op)

    def get_app_name(self):
        '''Get the application name as advertised to the pulseaudio server.'''
        # TODO move app name into pyglet.app (also useful for OS X menu bar?).
        import sys
        return sys.argv[0]

    def py_serverinfo_cb(pulse,context,svinfo,user=None):
        pass
        
    def py_clientinfo_cb(pulse,context, cinfo, eol, user=None):
        pass
        
    def py_sinkinfo_cb(pulse,context, sinfo, eol, user=None):
        print "sink"
    
    def py_sinkinputinfo_cb(pulse,context, siinfo, eol, user=None):
        print "py_sinkinput"
            
    def py_subscribe_cb(pulse,context,event,idx ,userdata = None):
        print "py_subscribe"
        
    def py_success_cb(pulse,context,success,user=None):
    	print "Py_Success",context, success, user
    
    def py_state_cb(pulse,context,userdata = None):
        print "State",context
        pass

p = PulseAudio()
p.connect("TestApp")
gtk.main()
